#pragma once

#include "zen_ticker.h"
#include "zen_print.h"

#include <functional>
#include <chrono>
#include <string>
#include <map>
#include <iostream>

namespace Zen
{
    class ConsoleTester
    {
      public:
        void AddTestCase(std::string const& name, std::function<void()> func)
        {
            if (func)
                mTests[name] = func;
            else
                mTests.erase(name);
        }
        void ShowCases()
        {
            print("select a case:");
            for (auto& c : mTests)
            {
                print("> ", c.first);
            }
        }
        void RunTest(std::string const& name)
        {
            auto iter = mTests.find(name);
            if (iter == mTests.end())
            {
                print("No test case named:" + name);
            }
            else
            {
                print(std::string(10, '-'));
                auto sec = FunctionUseSeconds(mTests[name])();
                print("run <", name, "> use time", sec, "seconds");
                print(std::string(10, '-'));
            }
        }

      private:
        Zen::Printer<char> print{ ' ', '\n' };
        std::map<std::string, std::function<void()>> mTests;
    };
} // namespace Zen

/**

Zen::ConsoleTester* GetTester()
{
    static Zen::ConsoleTester tester;
    return &tester;
}
// TODO: add test case before main.

int main(int argc, const char* argv[])
{
    auto t = GetTester();

    t->AddTestCase("quit", std::bind(&exit, 0));
    t->AddTestCase("show", [t]() { t->ShowCases(); });

// TODO: add test case in main.

    t->ShowCases();

    while (cin.good())
    {
        std::cin.clear();
        std::string name;
        std::cin >> name;
        t->RunTest(name);
    }
    return 0;
}

*/
